package com.yunxi.service.dubboService.impl.dealer;
import com.yunxi.model.dealer.Partner;
import com.yunxi.model.dealer.PartnerType;
import com.yunxi.service.localService.dealer.PartnerTypeService;
import java.util.Date;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.yunxi.account.pojo.PartnerAmountRespVO;
import com.yunxi.baseDataToHub.pojo.sap.PartnerFundDetailVO;
import com.yunxi.baseDataToHub.pojo.sap.PartnerFundVO;
import com.yunxi.baseDataToHub.service.sap.SapDubboService;
import com.yunxi.core.web.ApiResult;
import com.yunxi.core.web.LoginInfo;
import com.yunxi.core.web.ResponseUtil;
import com.yunxi.dealer.pojo.*;
import com.yunxi.dealer.service.PartnerAccountDubboService;
import com.yunxi.model.dealer.PartnerAccount;
import com.yunxi.service.localService.dealer.PartnerAccountService;
import com.yunxi.service.localService.dealer.PartnerService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 渠道商帐户 服务实现类
 * </p>
 *
 * @author
 * @since 2019-05-18
 */
//@com.alibaba.dubbo.config.annotation.Service(version = "${demo.service.version}",
//        application = "${dubbo.application.id}",
//        protocol = "${dubbo.protocol.id}",
//        registry = "${dubbo.registry.id}"
//)
public class PartnerAccountDubboServiceImpl implements PartnerAccountDubboService {

   private static final Logger logger = LoggerFactory.getLogger(PartnerAccountDubboServiceImpl.class);

   @Autowired
   @Qualifier(value = "partnerAccountServiceImpl")
   PartnerAccountService partnerAccountService;

   @Autowired
   @Qualifier(value = "sapDubboServiceImpl")
   SapDubboService sapDubboServiceImpl;

   @Autowired
   @Qualifier(value = "partnerServiceImpl")
   PartnerService partnerService;

    @Autowired
    @Qualifier(value = "partnerTypeServiceImpl")
    PartnerTypeService partnerTypeService;


    @Override
   public PartnerAccountVO getById(String id) throws InvocationTargetException, IllegalAccessException {
      PartnerAccount partnerAccount = partnerAccountService.getById(id);
      PartnerAccountVO partnerAccountVO = new PartnerAccountVO();
      BeanUtils.copyProperties(partnerAccount, partnerAccountVO);
      return partnerAccountVO;
   }

   @Override
   public void saveOrUpdate(PartnerAccountVO partnerAccountVO, LoginInfo loginInfo) throws InvocationTargetException, IllegalAccessException {
      if (StringUtils.isEmpty(partnerAccountVO.getAccountId())) {
         partnerAccountVO.setCreateBy(loginInfo.getRealName());
      }
      partnerAccountVO.setUpdateBy(loginInfo.getRealName());
      PartnerAccount partnerAccount = new PartnerAccount();
      BeanUtils.copyProperties(partnerAccountVO, partnerAccount);
      partnerAccountService.saveOrUpdate(partnerAccount);
   }

   @Override
   public void removeById(String id) {
      partnerAccountService.removeById(id);
   }

   @Override
   @Transactional
   public PageInfo<PartnerAccountVO> findPageByVO(PartnerAccountVO partnerAccountVO, Integer pageNum, Integer pageSize,LoginInfo loginInfo) throws Exception {
      String partnerCode = "";
      if (StringUtils.isNotEmpty(partnerAccountVO.getPartnerName())){
         partnerCode = partnerService.getPartnerCodeByPartnerName(partnerAccountVO.getPartnerName());
         partnerAccountVO.setPartnerCode(partnerCode);
      }

      //根据渠道代码查询渠道资金 PMS->ERP
      if (StringUtils.isNotEmpty(partnerAccountVO.getPartnerCode())){
         ApiResult apiResult = getPartnerFundsFromERP(partnerAccountVO, loginInfo);
         if (400 == apiResult.getCode()){
            throw new Exception("PMS获取SAP同步渠道资金错误");
         }
         if (200 != apiResult.getCode()){
            throw new Exception(apiResult.getMsg());
         }
      }

      PageInfo<PartnerAccountVO> pageInfo = partnerAccountService.pageByVo(partnerAccountVO, pageNum, pageSize);

      return pageInfo;

   }

   @Override
   @Transactional
   public ApiResult load(String partnerCode, String datam, String datbi) {
//    查询渠道资金明细   根据渠道code 记账开始日期和记账结束日期
      return getPartnerFundsDetailFromERP(partnerCode, datam, datbi);

//      return partnerAccountService.load(partnerCode, datam, datbi);
   }

   /**
    * 查询渠道资金明细
    * @param partnerCode 根据渠道code
    * @param datam 记账开始日期
    * @param datbi 和记账结束日期
    * @return
    */
   private ApiResult getPartnerFundsDetailFromERP(String partnerCode, String datam, String datbi) {
      PartnerFundDetailVO partnerFundDetailVO = new PartnerFundDetailVO();
      partnerFundDetailVO.setKunnr(partnerCode);
      partnerFundDetailVO.setDatam(datam);
      partnerFundDetailVO.setDatbi(datbi);
      try {
         ApiResult apiResult = sapDubboServiceImpl.findpartnerFundDetailBySap(partnerFundDetailVO);
         if(400 == apiResult.getCode()){

            return ResponseUtil.fail(400,"PMS获取SAP系统渠道资金明细失败");
         }
         if (200 != apiResult.getCode()) {
            logger.error("SAP接口调用，渠道商资金账户[明细]获取失败，事务回滚!");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseUtil.fail(-1, "SAP接口调用，渠道商资金账户获取失败，事务回滚!");
         }
         List<PartnerFundsDetailVO> partnerFundsDetailVOS = (List) JSON.parseArray((String) apiResult.getData(),PartnerFundsDetailVO.class);
         ArrayList<PartnerAccountTransRecordVO> list = new ArrayList<>();
         for (PartnerFundsDetailVO fundsDetailVO : partnerFundsDetailVOS) {
            PartnerAccountTransRecordVO recordVO = new PartnerAccountTransRecordVO();
            recordVO.setRecordId("");//主键
            recordVO.setAccountId("");//帐户id

            QueryWrapper<PartnerAccount> wrapper = new QueryWrapper<>();
            HashMap<String, Object> map = new HashMap<>();
            map.put("ACCOUNT_TYPE_CODE",fundsDetailVO.getSdabw());
            map.put("PARTNER_CODE",partnerCode);
            wrapper.allEq(map);
            List<PartnerAccount> partnerAccounts = partnerAccountService.list(wrapper);
            if (partnerAccounts!=null && partnerAccounts.size()>0){
               recordVO.setAccountCode(partnerAccounts.get(0).getAccountCode());//帐户代码
            }

            recordVO.setTransTime(new Date());//交易时间
            recordVO.setTransDate( fundsDetailVO.getBudat() );//交易日期  记账日期
            recordVO.setVoucherNo(fundsDetailVO.getBelnr());//会计凭证号
            recordVO.setAccountTypeCode(fundsDetailVO.getSdabw());//帐户类型
            recordVO.setAmount(new BigDecimal("0"));//交易金额
            recordVO.setBusNo(fundsDetailVO.getBstkd());//业务编号
            recordVO.setVoucherDate(new Date());//会计凭证日期
            recordVO.setCreateTime(new Date());
            recordVO.setUpddateTime(new Date());
            recordVO.setCreateBy("");
            recordVO.setUpdateBy("");
            recordVO.setBuzei(fundsDetailVO.getBuzei());//行项目
            recordVO.setGjahr(fundsDetailVO.getGjahr());//年度
            recordVO.setBukrs(fundsDetailVO.getBukrs());//公司代码
            recordVO.setPartnerCode(fundsDetailVO.getKunnr());//渠道商代码
            recordVO.setSx(fundsDetailVO.getSx());//业务交易方式
//业务交易方式  01 整车扣款；
//            02 配件扣款；
//            03 银企上账；
//            04 经销商返还上账；
//            05 经销商返还发放；
//            06 经销商返还结算-现金；
//            07 经销商返还结算-预收；
            recordVO.setDmbtr(fundsDetailVO.getDmbtr());//异动金额
            recordVO.setWaers(fundsDetailVO.getWaers());//币种
            recordVO.setBstkd(fundsDetailVO.getBstkd());//关联业务单据编号
            recordVO.setSgtxt(fundsDetailVO.getSgtxt());//财务文本
            recordVO.setCpudt(fundsDetailVO.getCpudt());//会计凭证输入日期
            recordVO.setCputm(fundsDetailVO.getCputm());//输入时间

            list.add(recordVO);
         }
         return ResponseUtil.ok(list);
      } catch (Exception e) {
         e.printStackTrace();
         TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
         logger.error("SAP接口调用，渠道商资金账户[明细]获取失败，事务回滚!");
         return ResponseUtil.fail(-1, "SAP接口调用，渠道商资金账户获取失败，事务回滚!");
      }
   }

   @Override
   public List<PartnerAccountOneVO> listByGroup(PartnerAccountVO partnerAccountVO, LoginInfo loginInfo) {
      return partnerAccountService.listByGroup(partnerAccountVO, loginInfo);
   }

   @Override
   @Transactional
   public ApiResult pageByGroup(PartnerAccountVO partnerAccountVO, Integer pageNum, Integer pageSize, LoginInfo loginInfo) throws Exception{
      String partnerCode = "";
      if (StringUtils.isNotEmpty(partnerAccountVO.getPartnerName())){
         partnerCode = partnerService.getPartnerCodeByPartnerName(partnerAccountVO.getPartnerName());
         partnerAccountVO.setPartnerCode(partnerCode);
      }
        //过滤 金融伙伴，银行机构    过滤冻结状态  过滤退网状态
       partnerAccountVO.setExcludeType(1);
      ApiResult apiResult =null ;
      //根据渠道代码查询渠道资金 PMS->ERP
      if (StringUtils.isNotEmpty(partnerAccountVO.getPartnerCode())){
          //调用SAP接口之前 校验渠道是否存在 且不为金融伙伴，银行机构
          QueryWrapper<PartnerType> queryWrapper  = new QueryWrapper<PartnerType>();
          queryWrapper.like("PARTNER_CODE",partnerAccountVO.getPartnerCode());
          PartnerType partnerType = partnerTypeService.getOne(queryWrapper);

         QueryWrapper<Partner> queryWrapper2  = new QueryWrapper<Partner>();
         queryWrapper2.like("PARTNER_CODE",partnerAccountVO.getPartnerCode());
         Partner partner= partnerService.getOne(queryWrapper2);

          if(partnerType==null){
              return ResponseUtil.fail(-1,"渠道商代码["+partnerAccountVO.getPartnerCode()+"]不存在,请核实!");
          }else if("F01".equals(partnerType.getAccountGroupCode())||"B01".equals(partnerType.getAccountGroupCode())){
              return ResponseUtil.fail(-1,"渠道商代码["+partnerAccountVO.getPartnerCode()+"]为金融伙伴或银行机构渠道商，无法查询资金!");
          }else if (partner.getStatus()==3){
               // 过滤冻结状态
             return ResponseUtil.fail(-1,"渠道商代码["+partnerAccountVO.getPartnerCode()+"]为冻结渠道商，无法查询资金!");
          } else if (partner.getStatus()==2){
         // 过滤退网状态
         return ResponseUtil.fail(-1,"渠道商代码["+partnerAccountVO.getPartnerCode()+"]为退网渠道商，无法查询资金!");
      }
             apiResult = getPartnerFundsFromERP(partnerAccountVO, loginInfo);
         if (400 == apiResult.getCode()){
            return ResponseUtil.fail(-1,"PMS获取SAP同步渠道资金错误");
         }
         if (200 != apiResult.getCode()){
            return ResponseUtil.fail(apiResult.getCode(),apiResult.getMsg());
         }
      }else{
          // 没有输入渠道代码 拉取当前分页的所有数据
          PageInfo  pageInfo = partnerAccountService.pageByGroup(partnerAccountVO,pageNum,pageSize,loginInfo);
          List<PartnerAccountOneVO> list=pageInfo.getList();
          StringBuffer message  = new StringBuffer();
          Boolean flag =  true;
         for(PartnerAccountOneVO partnerAccountOne:list){
          partnerAccountVO.setPartnerCode(partnerAccountOne.getPartnerCode());
          apiResult = getPartnerFundsFromERP(partnerAccountVO, loginInfo);
          if (400 == apiResult.getCode()){
              return ResponseUtil.fail(-1,"PMS获取SAP同步渠道资金错误");
          }
          if (200 != apiResult.getCode()){
            flag = false;
            message.append(apiResult.getMsg()+" ");
          }

          partnerAccountVO.setPartnerCode(null);
       }
//         if (!flag){
//            return ResponseUtil.fail(-1,message.toString());
//         }
      }



      return ResponseUtil.ok( partnerAccountService.pageByGroup(partnerAccountVO,pageNum,pageSize,loginInfo));

   }

   /**
    * 根据渠道代码查询渠道资金 PMS->ERP
    *
    * @param partnerAccountVO
    * @param loginInfo
    * @return
    */
   private ApiResult getPartnerFundsFromERP(PartnerAccountVO partnerAccountVO, LoginInfo loginInfo) {
      PartnerFundVO partnerFundVO = new PartnerFundVO();
      partnerFundVO.setKunnr(partnerAccountVO.getPartnerCode());
      ApiResult sapResult = null;
      try {
         sapResult = sapDubboServiceImpl.findPartnerFundBySap(partnerFundVO);
         if(400 == sapResult.getCode()){
            String data = (String) sapResult.getData();
            return ResponseUtil.fail(400,data);
         }
         if (200 != sapResult.getCode()) {
            logger.error(partnerAccountVO.getPartnerCode()+"，SAP接口调用，渠道商资金账户获取失败，事务回滚!"+sapResult.getCode()+sapResult.getMsg());
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            QueryWrapper<PartnerAccount> wrapper = new QueryWrapper<>();
            wrapper.eq("PARTNER_CODE",partnerAccountVO.getPartnerCode());
            PartnerAccount partnerAccount = new PartnerAccount();
            partnerAccount.setMemo(partnerAccountVO.getPartnerCode()+"渠道商资金账户获取失败"+sapResult.getCode()+sapResult.getMsg());
            partnerAccountService.update(partnerAccount, wrapper);
            return ResponseUtil.fail(sapResult.getCode(),partnerAccountVO.getPartnerCode()+"渠道商资金账户获取失败"+sapResult.getCode()+sapResult.getMsg());
         }
         List<PartnerAmountRespVO> list = (List)JSON.parseArray((String) sapResult.getData(),PartnerAmountRespVO.class);
         /*TODO : 对接SAP 渠道资金查询 接口字段不明确
                  BUKRS	公司代码
                  KKBER	信用控制范围
                  KLIMK	信用限额
                  KLPRZ	已使用的信贷限额
         */
         //更新渠道资金
         QueryWrapper<PartnerAccount> wrapper = new QueryWrapper<>();
         wrapper.eq("PARTNER_CODE",partnerAccountVO.getPartnerCode());
         PartnerAccount partnerAccount = new PartnerAccount();
         partnerAccount.setMemo("");
         partnerAccountService.update(partnerAccount, wrapper);

         for (PartnerAmountRespVO partnerAmountRespVO : list) {
            updatePartnerAccount(partnerAmountRespVO, partnerAmountRespVO.getCashtotal(), partnerAmountRespVO.getCashbal(),"A");//现金
            updatePartnerAccount(partnerAmountRespVO, partnerAmountRespVO.getRebatetotal(), partnerAmountRespVO.getRebatebal(),"9");//返利
            updatePartnerAccount(partnerAmountRespVO, partnerAmountRespVO.getThirdtotal(), partnerAmountRespVO.getThirdbal(),"1");//三方承兑-银票
            updatePartnerAccount(partnerAmountRespVO, partnerAmountRespVO.getFstotal(), partnerAmountRespVO.getFsbal(),"2");//融资
            updatePartnerAccount(partnerAmountRespVO, partnerAmountRespVO.getOthtotal(), partnerAmountRespVO.getOthbal(),"3");//其他
         }
      } catch (Exception e) {
         logger.error("SAP接口调用异常，渠道商资金账户获取失败，事务回滚!", e);
         TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
         return ResponseUtil.fail(sapResult.getCode(),"接口调用异常，渠道商资金账户获取失败"+sapResult.getCode()+sapResult.getMsg());
      }
      return ResponseUtil.ok();
   }

   /**
    * 更新渠道资金
    *
    * @param partnerAmountRespVO
    * @param total
    * @param balance
    * @param accountTypeCode
    * @param
    */
   private void updatePartnerAccount(PartnerAmountRespVO partnerAmountRespVO, String total, String balance, String accountTypeCode) {
      if (StringUtils.isNotEmpty(total)) {
         PartnerAccount partnerAccount = new PartnerAccount();
         partnerAccount.setPartnerCode(partnerAmountRespVO.getKunnr());
         partnerAccount.setAccountTypeCode(accountTypeCode);
         partnerAccount.setAccountAmount(new BigDecimal(total));
         partnerAccount.setAccountBalance(new BigDecimal(balance));
         QueryWrapper<PartnerAccount> wrapper = new QueryWrapper<>();
         HashMap<String, String> map = new HashMap<>();
         map.put("PARTNER_CODE",partnerAccount.getPartnerCode());
         map.put("ACCOUNT_TYPE_CODE",partnerAccount.getAccountTypeCode());
         wrapper.allEq(map);
         partnerAccountService.update(partnerAccount, wrapper);
      }
   }

   @Override
   public List listByVo(PartnerAccountVO v) {
      return partnerAccountService.listByVo(v);
   }


}
